import CryptoJS from "crypto-js"; 

class CrossFileReader {
	// 标识入参是否是数组
	isArray = false;
	fileArr = [];
	fileResArr = [];
	reader = null;
	constructor(file) {
		this.#init(file)
	}
	// 初始化
	#init(file) {
		this.fileResArr = [];
		if (Array.isArray(file)) {
			this.fileArr = file;
			this.isArray = true; 
		} else {
			this.fileArr = [file];
			this.isArray = false;
		}
		// #ifdef MP
		this.reader = uni.getFileSystemManager()
		// #endif
	}
	// resolve拦截器
	#resolveHandler(resolve) { // 添加 resolve 参数
		this.fileResArr.sort((a, b) => a.index - b.index);
		resolve(this.isArray ? this.fileResArr : this.fileResArr[0]);
		this.fileResArr = [];
		
	}
	// #ifdef MP    
	// 微信小程序读取文件处理
	#wxReaderHandler(file, index, resolve, encoding = '', resHandlerFun = null) {
		this.reader.readFile({
			filePath: file.path, // 这里填入文件路径
			encoding: encoding, // 留空，表示读取原始二进制数据
			success: (res) => {
				const filename = file.path.match(/\/([^\/]+\.[a-zA-Z0-9]+)$/)[1];
				let resObj = {
					fileName: filename,
					result: res.data,
					type: 'ArrayBuffer',
					index
				}
				if (resHandlerFun) {
					resObj = resHandlerFun(resObj)
				}
				this.fileResArr.push(resObj);
				if (this.fileResArr.length === this.fileArr.length) {
					this.#resolveHandler(resolve);
				}
			},
			fail: (err) => {
				console.error('读取文件失败', err);
			}
		});
	}
	// #endif

	// 读取文件 DataURL
	readAsDataURL(file) {
		this.#init(file)
		return new Promise((resolve, reject) => {
			this.fileArr.forEach((file, index) => {
				// #ifdef WEB
				const reader = new FileReader();
				reader.onload = (e) => {
					try {
						this.fileResArr.push({
							fileName: file.name,
							result: e.target.result,
							type: 'DataURL',
							index
						});

						// 如果所有文件都已经处理完毕，解析 Promise
						if (this.fileResArr.length === this.fileArr.length) {
							this.#resolveHandler(resolve);
						}
					} catch (err) {
						reject(err);
					}
				};

				reader.onerror = (err) => {
					reject(err);
				};
				reader.readAsDataURL(file);
				// #endif

				// js引擎版编译为App时
				// #ifdef APP-PLUS
				const tempPath = file.path;
				// console.log('##### tempPath', tempPath);
				plus.io.resolveLocalFileSystemURL(tempPath, (entry) => {
					entry.file((file) => {
						// console.log('##### file', file);
						const reader = new plus.io.FileReader();
						reader.onload = (e) => {
							// console.log('##### e.target.result');
							// console.log('##### this',this)
							// console.log('##### fileResArr1',this.fileResArr)
							this.fileResArr.push({
								fileName: file.name,
								result: e.target.result,
								type: 'DataURL',
								index
							});
							// console.log('##### fileResArr2',this.fileResArr);
							if (this.fileResArr.length === this.fileArr
								.length) {
								this.#resolveHandler(resolve);
							}
						};
						reader.readAsDataURL(file);
					}, function(err) {
						reject(err);
					});
				}, function(err) {
					reject(err);
				});
				// #endif

				// 微信小程序
				// #ifdef MP-WEIXIN
				this.#wxReaderHandler(file, index, resolve, 'base64', (obj) => {
					const extension = obj.fileName.split('.').pop().toLowerCase();
					const mimeTypes = {
					    'png': 'image/png',
					    'jpg': 'image/jpeg',
					    'jpeg': 'image/jpeg',
					    'gif': 'image/gif',
					    'bmp': 'image/bmp',
					    'webp': 'image/webp',
					    'svg': 'image/svg+xml',
					    'mp3': 'audio/mpeg',
					    'wav': 'audio/wav',
					    'mp4': 'video/mp4',
					    'pdf': 'application/pdf',
					    'json': 'application/json',
					    'txt': 'text/plain',
					    'html': 'text/html',
					};
					mimeTypes[extension] || 'application/octet-stream'; // 默认为二进制流
					obj.result = `data:${mimeTypes[extension]};base64,${obj.result}`
					obj.type = 'DataURL';
					return obj
				})
				// #endif

			});
		});
	}
	// 读取文件 ArrayBuffer
	readAsArrayBuffer(file) {
		this.#init(file)
		return new Promise((resolve, reject) => {
			this.fileArr.forEach((file, index) => {
				// web 或 h5
				// #ifdef WEB
				const reader = new FileReader();
				reader.onload = (e) => {
					try {
						this.fileResArr.push({
							fileName: file.name,
							result: e.target.result,
							type: 'ArrayBuffer',
							index
						});
						// 如果所有文件都已经处理完毕，解析 Promise
						if (this.fileResArr.length === this.fileArr.length) {
							this.#resolveHandler(resolve);
						}
					} catch (err) {
						reject(err);
					}
				};

				reader.onerror = (err) => {
					reject(err);
				};

				// 读取文件为 ArrayBuffer
				reader.readAsArrayBuffer(file);
				// #endif

				// js引擎版编译为App时
				// #ifdef APP-PLUS
				// 直接调用 readAsDataURL 方法
				this.readAsDataURL(file).then(res => {
					if (!Array.isArray(res)) {
						res = [res];
					}
					res.forEach(item => {
						const base64 = item.result.split('base64,')[1];
						const arrayBuffer = uni.base64ToArrayBuffer(base64);
						item.result = arrayBuffer;
						item.type = 'ArrayBuffer';
					})
					this.fileResArr = [...res];
					this.#resolveHandler(resolve);
				}).catch(err => {
					reject(err);
				})
				// #endif

				// 微信小程序
				// #ifdef MP-WEIXIN
				this.#wxReaderHandler(file, index, resolve)
				// #endif

			});
		});
	}

	readAsText(file){
		this.#init(file)
		return new Promise((resolve, reject) => {
			this.fileArr.forEach((file, index) => {
				// web 或 h5
				// #ifdef WEB
				const reader = new FileReader();
				reader.onload = (e) => {
					try {
						this.fileResArr.push({
							fileName: file.name,
							result: e.target.result,
							type: 'Text',
							index
						});
						// 如果所有文件都已经处理完毕，解析 Promise
						if (this.fileResArr.length === this.fileArr.length) {
							this.#resolveHandler(resolve);
						}
					} catch (err) {
						reject(err);
					}
				};
		
				reader.onerror = (err) => {
					reject(err);
				};
		
				// 读取文件为 ArrayBuffer
				reader.readAsText(file);
				// #endif
		
				// js引擎版编译为App时
				// #ifdef APP-PLUS
				const timeoutDuration = 5000; // 超时设置为5秒，根据需要调整
				// 超时提示函数
				function showTimeoutWarning() {
				    console.log('文件读取超时，可能文件过大');
				}
				
				const tempPath = file.path;
				plus.io.resolveLocalFileSystemURL(tempPath, (entry) => {
					entry.file((file) => {
						console.log('##### file', file);
						const reader = new plus.io.FileReader();
						reader.onload = (e) => {
							console.log('##### e.target.result');
							this.fileResArr.push({
								fileName: file.name,
								result: e.target.result,
								type: 'Text',
								index
							});
							// console.log('##### fileResArr2',this.fileResArr);
							if (this.fileResArr.length === this.fileArr.length) {
								this.#resolveHandler(resolve);
							}
							clearTimeout(timeoutTimer);

						};
						reader.onerror = (err) => {
							console.error('FileReader error', err);
							clearTimeout(timeoutTimer); // 清除超时定时器
						};
						reader.readAsText(file);
						const timeoutTimer = setTimeout(showTimeoutWarning, timeoutDuration);

					}, function(err) {
						reject(err);
					});
				}, function(err) {
					reject(err);
				});
				// #endif
		
				// 微信小程序
				// #ifdef MP-WEIXIN
				this.#wxReaderHandler(file, index, resolve, 'utf8',(obj) => {
					obj.type = 'Text'
					return obj
				})
				// #endif
		
			});
		});
	}
	
	// 单位: kb
	getStorageSize(){
		return new Promise((resolve, reject) => {
			try {
				const res = uni.getStorageInfoSync()
				resolve(res.currentSize) 
			} catch (error) {
				reject(error)
			}
		})
		
	}
	getFileCatchSize(){
		// 未完成 弃用
		this.#init()
		return new Promise((resolve, reject) => {
			// #ifdef WEB
				resolve(0)
			// #endif
			
			// #ifdef MP
			this.reader.getFileInfo({
				success(res) {
					// console.log(res.fileList); // 文件列表及其信息
					console.log('### getSavedFileList res',res);
					resolve(res)
					// const total = res.fileList.reduce((prev, current) => { prev + current.size}, 0)
					// resolve(total)
				},
				fail(error) {
					console.error(error);
					reject(error);
				}
			});
			// #endif
			
			// #ifdef APP-PLUS
			const cachePath = plus.io.cache;  // 获取缓存目录路径
			let totalSize = 0;
			// 读取缓存目录中的文件
			plus.io.resolveLocalFileSystemURL(cachePath, function(entry) {
				let directoryReader = entry.createReader();
				directoryReader.readEntries(function(entries) {
					let filesProcessed = 0;
					const totalFiles = entries.length;
	
					if (totalFiles === 0) {
						resolve(totalSize);  // 如果目录为空，返回0
					}
					// 遍历文件夹中的文件
					entries.forEach(function(entry) {
						if (entry.isFile) {
							entry.getMetadata(function(metadata) {
								totalSize += metadata.size; // 累加文件大小
								filesProcessed++;
								if (filesProcessed === totalFiles) {
									resolve(totalSize); // 所有文件处理完成后，返回总大小
								}
							});
						} else {
							filesProcessed++;
							if (filesProcessed === totalFiles) {
								resolve(totalSize); // 如果目录中有子目录，跳过它们
							}
						}
					});
				}, function(error) {
					reject('读取缓存目录失败: ' + error.message);  // 出错时拒绝 Promise
				});
			});
			// #endif
		})
		
	}
	// 提供静态方法, 用于直接调用
	static readAsDataURL(file) {
		return new CrossFileReader().readAsDataURL(file)
	}
	static readAsArrayBuffer(file) {
		return new CrossFileReader().readAsArrayBuffer(file)
	}
	static readAsText(file) {
		return new CrossFileReader().readAsText(file)
	}
	// 单位: kb
	static getStorageSize() {
		return new CrossFileReader().getStorageSize()
	}
	static getFileCatchSize() {
		return new CrossFileReader().getFileCatchSize()
	}
}

export default CrossFileReader